package com.lib.image.picker

import android.Manifest
import android.annotation.SuppressLint
import android.app.Activity
import android.app.Dialog
import android.content.Intent
import android.content.pm.ActivityInfo
import android.graphics.BitmapFactory
import android.net.Uri
import android.os.Bundle
import android.util.Log
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.WindowManager
import android.widget.FrameLayout
import android.widget.Toast
import androidx.appcompat.app.AppCompatActivity
import androidx.core.content.ContextCompat
import androidx.fragment.app.DialogFragment
import com.ftd.livepermissions.LivePermissions
import com.ftd.livepermissions.PermissionResult
import com.lib.image.R
import com.lib.image.ex.RxUtils
import com.lib.image.picker.Type.*
import com.lib.image.until.PermissionsUntil
import com.providerlib.fileprovider.FileProvider7
import com.zhihu.matisse.Matisse
import com.zhihu.matisse.MimeType
import com.zhihu.matisse.engine.impl.GlideEngine
import com.zhihu.matisse.internal.entity.CaptureStrategy
import io.reactivex.rxjava3.core.Observable
import kotlin.properties.Delegates

/**
 * @Author: shalei
 * @Date: 2019-10-25 13:58
 * @Desc: 用来选择相册，拍照，视频，文件等等
 * **/
class FileActionSheet : DialogFragment() {

    companion object {

        private const val CODE_CAMERA: Int = 99
        private const val REQUEST_CODE_CHOOSE = 101
        private const val KEY_MAX = "KEY_MAX";
        private const val KEY_ACTION = "KEY_ACTION";

        @JvmStatic
        fun newInstance4Photo(max: Int): FileActionSheet {
            val bundle = Bundle()
            bundle.putInt(KEY_MAX, max)
            bundle.putInt(KEY_ACTION, TYPE_PHOTO);
            val fileActionSheet = FileActionSheet()
            fileActionSheet.arguments = bundle
            return fileActionSheet
        }

        @JvmStatic
        fun newInstance4Video(max: Int): FileActionSheet {
            val bundle = Bundle()
            bundle.putInt(KEY_MAX, max)
            bundle.putInt(KEY_ACTION, TYPE_VIDEO);
            val fileActionSheet = FileActionSheet()
            fileActionSheet.arguments = bundle
            return fileActionSheet
        }

        @JvmStatic
        fun newInstance4File(max: Int): FileActionSheet {
            val bundle = Bundle()
            bundle.putInt(KEY_MAX, max)
            bundle.putInt(KEY_ACTION, TYPE_FILE);
            val fileActionSheet = FileActionSheet()
            fileActionSheet.arguments = bundle
            return fileActionSheet
        }
    }

    /**
     * 权限请求框架
     */
    private lateinit var rxPermissions: LivePermissions

    /**
     * 底部弹窗效果
     */
    private lateinit var mIosBottomListWindow: IosBottomListWindow

    private lateinit var mCameraName: String

    /**
     * 选择后的图片保存到这个集合中
     */
    private lateinit var mSelectImageList: ArrayList<String>

    private var action by Delegates.notNull<Int>()
    private var max by Delegates.notNull<Int>()
    private var firstIn = true

    private fun isGranted(permission: String): Boolean {
        return PermissionsUntil.isGranted(requireContext(), permission)
    }

    override fun onCreateDialog(savedInstanceState: Bundle?): Dialog {
        return Dialog(requireContext(), R.style.MyDialog)
    }

    override fun onCreateView(inflater: LayoutInflater, container: ViewGroup?, savedInstanceState: Bundle?): View? {
        return inflater.inflate(R.layout.layout_action_sheet, container, false)
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)
        dialog?.window?.setBackgroundDrawable(ContextCompat.getDrawable(requireContext(), android.R.color.transparent));
    }

    override fun onActivityCreated(savedInstanceState: Bundle?) {
        super.onActivityCreated(savedInstanceState)
        rxPermissions = LivePermissions(this)
        mSelectImageList = arrayListOf()
        action = requireArguments().getInt(KEY_ACTION)
        max = requireArguments().getInt(KEY_MAX)
        mIosBottomListWindow = getActionBottomWindow()

        val window = dialog?.window
        val windowParams = window?.attributes
        windowParams?.dimAmount = 0.0f
        windowParams?.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE;
        window?.attributes = windowParams;
        mIosBottomListWindow.show()
    }

    private fun getPhotoWindow(): IosBottomListWindow {
        return IosBottomListWindow(requireActivity())
                .setCancelButton("取消", 0)
                .addItem("拍照", 0) {

                    if (!isGranted(Manifest.permission.CAMERA)) {
                        requestCameraPermissions { openCamera() }
                        return@addItem
                    }
                    openCamera()
                }
                .addItem("相册", 0) {
                    if (!isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                        requestGalleryPermissions { openFile(MimeType.ofImage()) }
                        return@addItem
                    }
                    openFile(MimeType.ofImage())
                }
    }

    private fun getVideoWindow(): IosBottomListWindow {
        return IosBottomListWindow(requireActivity())
                .setCancelButton("取消", 0)
                .addItem("录制", 0) {
                    if (!isGranted(Manifest.permission.CAMERA)) {
                        requestCameraPermissions { openCamera() }
                        return@addItem
                    }
                    openCamera()
                }
                .addItem("相册", 0) {
                    if (!isGranted(Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                        requestGalleryPermissions {
                            openFile(MimeType.ofVideo())
                        }
                        return@addItem
                    }
                    openFile(MimeType.ofVideo())
                }
    }

    private fun getFileWindow(): IosBottomListWindow {
        val rootView = requireView().findViewById<FrameLayout>(R.id.root_view)
        return IosBottomListWindow(requireActivity(), rootView)
                .setCancelButton("取消", 0)
                .addItem("文件", 0) {
                    if (PermissionsUntil.isGranted(requireContext(), Manifest.permission.WRITE_EXTERNAL_STORAGE)) {
                        requestGalleryPermissions { openFile(MimeType.ofAll()) }
                        return@addItem
                    }
                    openFile(MimeType.ofAll())
                }
    }

    private fun getActionBottomWindow() = when (action) {
        TYPE_VIDEO -> getVideoWindow()
        TYPE_FILE -> getFileWindow()
        else -> getPhotoWindow()
    }

    @SuppressLint("CheckResult")
    private fun requestGalleryPermissions(runFunc: () -> Unit) {
        rxPermissions
            .request(Manifest.permission.WRITE_EXTERNAL_STORAGE)
            .observe(viewLifecycleOwner){
                if (it == PermissionResult.Grant) {
                    //通过
                    runFunc.invoke()
                    return@observe
                }
                Toast.makeText(activity?.applicationContext, "打开相册必须拥有读写权限！！！", Toast.LENGTH_SHORT)
                    .show()
            }
    }

    @SuppressLint("CheckResult")
    private fun requestCameraPermissions(runFunc: () -> Unit) {
        rxPermissions.request(Manifest.permission.CAMERA)
            .observe(viewLifecycleOwner) {
                if (it == PermissionResult.Grant) {
                    //通过
                    runFunc.invoke()
                    return@observe
                }
                Toast.makeText(activity?.applicationContext, "拍照必须拥有相机权限！！！", Toast.LENGTH_SHORT).show()
            }
    }

    private fun openCamera() {
        mCameraName = "sh_" + System.currentTimeMillis() + ".jpg"
        val cameraIntent = PhotoTakeService.getCameraIntent(activity?.applicationContext, mCameraName)
        if (cameraIntent.resolveActivity(activity?.packageManager!!) != null) {
            startActivityForResult(cameraIntent, CODE_CAMERA)
        }
    }

    /**
     * 打开相册
     */
    @SuppressLint("CheckResult")
    private fun openFile(mimeTypes: Set<MimeType>) {
        mSelectImageList.clear()
        if(activity == null){
            dismissAllowingStateLoss()
            return
        }
        Matisse.from(this)
            .choose(mimeTypes, false)
            .countable(true)
            .capture(true)
            .captureStrategy(
                CaptureStrategy(
                    true,
                    FileProvider7.getFileProviderName(activity),
                    "test"
                )
            )
            .maxSelectable(max)
            .gridExpectedSize(
                resources.getDimensionPixelSize(R.dimen.grid_expected_size)
            )
            .restrictOrientation(ActivityInfo.SCREEN_ORIENTATION_PORTRAIT)
            .thumbnailScale(0.85f)
            .imageEngine(GlideEngine())
            .showSingleMediaType(true)
            .originalEnable(true)
            .maxOriginalSize(10)
            .autoHideToolbarOnSingleTap(true)
            .forResult(REQUEST_CODE_CHOOSE)

    }

    /**
     * 拍照相机回调
     */
    override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?) {
        super.onActivityResult(requestCode, resultCode, data)
        if (resultCode != Activity.RESULT_OK) return
        val imgList = arrayListOf<String>()
        when (requestCode) {
            CODE_CAMERA -> {
                val cameraPath = PhotoTakeService.getCameraPath(activity, mCameraName)
                val newPath = PhotoTakeService.qualityCompress(
                    BitmapFactory.decodeFile(cameraPath.absolutePath),
                    activity
                )
                imgList.add(newPath)
                if (resultListListener != null) {
                    resultListListener!!.onResult(imgList)
                }
            }
            REQUEST_CODE_CHOOSE -> {
                val obtainPathResult = Matisse.obtainPathResult(data)
                qualityCompressBitmap(obtainPathResult)
            }
        }
    }

    @SuppressLint("CheckResult")
    private fun qualityCompressBitmap(pathList: MutableList<String>) {
        Observable.create<MutableList<String>> { em ->
            val paths = mutableListOf<String>()
            pathList.forEach { path->
                val newPath = PhotoTakeService.qualityCompress(
                    BitmapFactory.decodeFile(path),
                    activity
                )
                paths.add(newPath)
            }
            em.onNext(pathList)
            em.onComplete()
        }.compose(RxUtils.applySchedulers())
            .subscribe({
                val imgList = arrayListOf<String>()
                imgList.addAll(it)
                if (resultListListener != null) {
                    resultListListener!!.onResult(imgList)
                }
            }, { th->
                activity?.let {
                    Toast.makeText(it, th.message, Toast.LENGTH_SHORT).show()
                }
            })
    }

    private var resultListListener: OnResultListListener? = null

    fun setOnResultListener(resultListListener: OnResultListListener): FileActionSheet {
        this.resultListListener = resultListListener
        return this
    }

    public fun isShow():Boolean {
        return showsDialog && isAdded && !isDetached
    }

    interface OnResultListListener {
        fun onResult(imgList: ArrayList<String>);
    }
}